﻿using Dataweb.NShape;
using Dataweb.NShape.Advanced;
using System.ComponentModel;

namespace cz.zcu.PreSti.Shapes
{
    public class ConnectorArrow : PolylineBase, IConnection
    {

        public override Shape Clone()
        {
            Shape result = new ConnectorArrow(Type, (Template)null);
            result.CopyFrom(this);
            return result;
        }

        protected internal ConnectorArrow(ShapeType shapeType, Template template)
            : base(shapeType, template)
        {
        }

        protected internal ConnectorArrow(ShapeType shapeType, IStyleSet styleSet)
			: base(shapeType, styleSet) {
		}

        [Category("Appearance")]
        [Description("Defines the line cap appearance of the line's beginning.")]
        [PropertyMappingId(PropertyIdStartCapStyle)]
        [RequiredPermission(Permission.Present)]
        public ICapStyle StartCapStyle
        {
            get
            {
                if (StartCapStyleInternal == null && Template == null) throw new NShapeException("Property StartCapStyle is not set.");
                return StartCapStyleInternal == null ? ((ConnectorArrow)Template.Shape).StartCapStyle : StartCapStyleInternal;
            }
            set
            {
                StartCapStyleInternal = (Template != null && value == ((ConnectorArrow)Template.Shape).StartCapStyle) ? null : value;
            }
        }


        [Category("Appearance")]
        [Description("Defines the line cap appearance of the line's ending.")]
        [PropertyMappingId(PropertyIdEndCapStyle)]
        [RequiredPermission(Permission.Present)]
        public ICapStyle EndCapStyle
        {
            get
            {
                if (EndCapStyleInternal == null && Template == null) throw new NShapeException("Property EndCapStyle is not set.");
                return EndCapStyleInternal == null ? ((ConnectorArrow)Template.Shape).EndCapStyle : EndCapStyleInternal;
            }
            set
            {
                EndCapStyleInternal = (Template != null && value == ((ConnectorArrow)Template.Shape).EndCapStyle) ? null : value;
            }
        }

        #region IConnection Members

        public bool IsFullyConnected()
        {
            return InputInfo().OtherShape != null && OutputInfo().OtherShape != null;
        }

        public ISymbol GetConnectedShape()
        {
            return (ISymbol)(InputInfo().OtherShape);
        }

        public int GetConnectedShapeGetterN()
        {
            ShapeConnectionInfo info = InputInfo();
            return Symbols.ControlPointIdToGetterN((ISymbol)(info.OtherShape), info.OtherPointId);
        }

        public int GetSetterN()
        {
            ShapeConnectionInfo info = OutputInfo();
            return Symbols.ControlPointIdToSetterN((ISymbol)(info.OtherShape), info.OtherPointId);
        }

        #endregion

        private ShapeConnectionInfo InputInfo()
        {
            ShapeConnectionInfo i = this.GetConnectionInfo(-1, null);
            if (Symbols.IsControlPointGetter(((ISymbol)(i.OtherShape)), i.OtherPointId)) return i;
            i = this.GetConnectionInfo(-2, null);
            if (Symbols.IsControlPointGetter(((ISymbol)(i.OtherShape)), i.OtherPointId)) return i;
            return ShapeConnectionInfo.Empty;
        }

        private ShapeConnectionInfo OutputInfo()
        {
            ShapeConnectionInfo i = this.GetConnectionInfo(-1, null);
            if (Symbols.IsControlPointSetter(((ISymbol)(i.OtherShape)), i.OtherPointId)) return i;
            i = this.GetConnectionInfo(-2, null);
            if (Symbols.IsControlPointSetter(((ISymbol)(i.OtherShape)), i.OtherPointId)) return i;
            return ShapeConnectionInfo.Empty;
        }

        internal static Shape CreateInstance(ShapeType shapeType, Template template)
        {
            return new ConnectorArrow(shapeType, template);
        }

    }
}
